package com.ghovos.usermangerpgdemo.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ghovos.usermangerpgdemo.common.result.GlobalResult;
import com.ghovos.usermangerpgdemo.common.result.GlobalResultEnum;
import com.ghovos.usermangerpgdemo.entity.ext.UserWithRoleIds;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author EdgarLiu(刘凌峰) <br/>
 * date: 2022/3/18 <br/>
 * time: 下午9:10 <br/>
 * email: EdgarLlf@foxmail.com
 */
@Component
@AllArgsConstructor
public class TokenInterceptor implements HandlerInterceptor {

    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        final ObjectMapper objectMapper = new ObjectMapper();

        // 1. 从头部获取token
        String token = request.getHeader("Authorization");
        String result = "";

        if (null != token && !"".equals(token)) {
            // 2. 判断redis中是有该token
            String userInfo = stringRedisTemplate.opsForValue().get("allow_list:" + token);
            if (userInfo == null) {
                // 无token
                result = objectMapper.writeValueAsString(GlobalResult.fail(GlobalResultEnum.UNAUTHORIZED));
            } else { // 有用户info， 返回成功
                UserWithRoleIds userWithRoleIds = objectMapper.readValue(userInfo, UserWithRoleIds.class);
                // 如果是1号admin 用户
                if (userWithRoleIds.getId() == 1) {
                    return true;
                }

                String[] split = request.getRequestURI().split("/\\d+$");
                if (split.length > 0) {

                    Set<String> allPermission = new LinkedHashSet<>();
                    userWithRoleIds.getRoleIds().forEach(roleId -> {
                        Set<String> roleIdSet = stringRedisTemplate.opsForSet().members("role:" + roleId);
                        allPermission.addAll(Objects.requireNonNull(roleIdSet));
                    });
                    if (allPermission.contains(split[0])) {
                        return true;
                    } else {
                        result = objectMapper.writeValueAsString(GlobalResult.fail(GlobalResultEnum.FORBIDDEN));
                    }
                } else {
                    // 2.2 url 错误
                    result = objectMapper.writeValueAsString(GlobalResult.fail(GlobalResultEnum.FORBIDDEN));
                }
            }
        } else {
            // 未携带token
            result = objectMapper.writeValueAsString(GlobalResult.fail(GlobalResultEnum.NOT_TOKEN));
        }
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(result);
        return false;
    }
}
